﻿using System;
using System.Reflection;
using AFCEPF.BankApplication.BLL;
using AFCEPF.BankApplication.DAL;
using AFCEPF.BankApplication.Tests.Utilities;
using NUnit.Framework;

namespace AFCEPF.BankApplication.Tests
{
    [TestFixture]
    internal class Test_ReflectionHelper
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {
            _person = new MockPerson("aa", "bb", DateTime.Now.Year);
            _personType = _person.GetType();
        }

        #endregion

        private MockPerson _person;
        private Type _personType;

        [Test]
        public void Test_Method_GetPropertyValue()
        {
            _person.Name = "aa";

            var s = (string) _person.GetPropertyValue("Name");

            Assert.AreEqual(s, _person.Name);
        }

        [Test]
        public void Test_Method_GetUniqueAttribute_OnProperty()
        {
            // on récupère la propriété Id (par exemple)..
            PropertyInfo property = _personType.GetProperty("Id");

            var fieldAttribute = property.GetUniqueAttribute<FieldAttribute>();
            Assert.NotNull(fieldAttribute);
        }


        [Test]
        public void Test_Method_GetUniqueAttribute_OnType()
        {
            TableAttribute tableAttribute;

            tableAttribute = _personType.GetUniqueAttribute<TableAttribute>();
            Assert.NotNull(tableAttribute);
        }


        [Test]
        public void Test_Method_ImplementsInterface_WithGenericInterface_OnClass()
        {
            Type implementor = typeof (Manager);
            bool result = implementor.ImplementsInterface<IRequestApprover<RequestBase>>();
            Assert.IsTrue(result);
        }


        [Test]
        public void Test_Method_ImplementsInterface_WithGenericInterface_OnInstance()
        {
            var implementor = new Manager();
            bool result = implementor.ImplementsInterface<IRequestApprover<RequestBase>>();
            Assert.IsTrue(result);
        }

        [Test]
        public void Test_Method_ImplementsInterface_WithNonGenericInterface_OnClass()
        {
            Type implementor = typeof (AccountBase);
            bool result = implementor.ImplementsInterface<IVisitable>();

            Assert.IsTrue(result);
        }


        [Test]
        public void Test_Method_ImplementsInterface_WithNonGenericInterface_OnInstance()
        {
            AccountBase implementor = Bank.Instance.Accounts.Create(new Customer("toto"), 1000);
            bool result = implementor.ImplementsInterface<IVisitable>();

            Assert.IsTrue(result);
        }

        [Test]
        public void Test_Method_IsDecoratedWith_OnProperty()
        {
            // on récupère la propriété Id (par exemple)..
            PropertyInfo property = _personType.GetProperty("Id");
            Assert.IsTrue(property.IsDecoratedWith<FieldAttribute>());
        }

        [Test]
        public void Test_Method_IsDecoratedWith_OnType()
        {
            // on récupère la propriété Id (par exemple)..            
            Assert.IsTrue(_personType.IsDecoratedWith<TableAttribute>());
        }

        [Test]
        public void Test_Method_SetPropertyValue()
        {
            ReflectionHelper.SetPropertyValue("Name", _person, "xx");
            Assert.IsTrue(_person.Name == "xx");
        }
    }
}